﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace GCELibrary.Current
{
    class TimeTriggerModel
    {
        public ThreadStart Method { get; protected set; }
        public TimeSpan TimeSpan { get;set; }
        public DateTime LastDateTime { get; set; }
        public Guid Key {get;protected set;}
        public TimeTriggerModel(ThreadStart method, TimeSpan timeSpan)
        {
            this.Method = method;
            this.TimeSpan = timeSpan;
            this.Key = Guid.NewGuid();
            this.LastDateTime = DateTime.Now;
            State = ThreadState.Unstarted;
        }
        public ThreadState State { get; set; }
        public void ThreadStart(object sender)
        {
            try
            {
                this.State = ThreadState.Running;
                this.Method();
            }
            catch
            {
                this.State = ThreadState.Aborted;
            }
            this.State = ThreadState.Stopped;
        }
    }
 
    /// <summary>
    /// 触发器服务器实现
    /// </summary>
    public class TimeTriggerService 
    {
        static Thread _timerThread = null;
        static TimeTriggerService()
        {
            SourceList = new List<TimeTriggerModel>();
            _timerThread = new Thread(Tick);
            _timerThread.Start();
        }
        static IList<TimeTriggerModel> SourceList { get; set; }
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="method"></param>
        /// <param name="interval">秒钟</param>
        /// <returns></returns>
        public static Guid Register(ThreadStart method, int interval)
        {
           return  Register(method, new TimeSpan(0, 0, interval));
        }
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="method"></param>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        public static Guid Register(ThreadStart method, TimeSpan timeSpan)
        {
            if (method == null || timeSpan == null )
                throw new ArgumentException();
            TimeTriggerModel model = new TimeTriggerModel(method, timeSpan);
            lock (SourceList)
            {
                SourceList.Add(model);
            }
            return model.Key;
         }
        /// <summary>
        /// 设置触发器间隔
        /// </summary>
        /// <param name="key"></param>
        /// <param name="interval"></param>
        /// <returns></returns>
        public static bool SetInterval(Guid key, int interval)
        {
            return SetInterval(key, new TimeSpan(0, 0, interval));
        }
        /// <summary>
        /// 设置触发器间隔
        /// </summary>
        /// <param name="key"></param>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        public static bool SetInterval(Guid key, TimeSpan timeSpan)
        {
            if (timeSpan == null) throw new ArgumentException();
            TimeTriggerModel model = null;
            lock (SourceList)
            {
                model = SourceList.FirstOrDefault(p => p.Key == key);
            }
            if (model == null)
                return false;
            model.TimeSpan = timeSpan;
            return true;
        }
        /// <summary>
        /// 注销服务
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool UnRegister(Guid key)
        {
            TimeTriggerModel model = null;
            lock (SourceList)
            {
                model = SourceList.FirstOrDefault(p => p.Key == key);
                if (model != null)
                {
                    SourceList.Remove(model);
                }
            }
            return model != null;
        }
        /// <summary>
        /// 轮洵方法
        /// </summary>
        protected static void Tick()
        {
            do
            {
                //需要触发的对象集
                IList<TimeTriggerModel> sourceList = null;
                lock (SourceList)
                {
                    sourceList = SourceList.ToList();
                }
                //遍历触发对象
                foreach (TimeTriggerModel model in sourceList)
                {
                    //如果超过设定的时间则把方法放入线程池进行调用
                    if ((DateTime.Now - model.LastDateTime) >= model.TimeSpan)
                    {
                        if (model.State == ThreadState.Unstarted || model.State == ThreadState.Stopped)
                        {
                            ThreadPool.QueueUserWorkItem(model.ThreadStart);
                        }
                        model.LastDateTime = DateTime.Now;
                    }
                }
                Thread.Sleep(1000);
            } while (true);
        }
         
    }

    /// <summary>
    /// 触发器服务器接口
    /// </summary>
    public interface ITimeTriggerService
    {
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="method"></param>
        /// <param name="interval"></param>
        /// <returns></returns>
        Guid Register(ThreadStart method, int interval);
        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="method"></param>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        Guid Register(ThreadStart method, TimeSpan timeSpan);
        /// <summary>
        /// 设置触发器间隔
        /// </summary>
        /// <param name="key"></param>
        /// <param name="interval"></param>
        /// <returns></returns>
        bool SetInterval(Guid key, int interval);
        /// <summary>
        /// 设置触发器间隔
        /// </summary>
        /// <param name="key"></param>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        bool SetInterval(Guid key, TimeSpan timeSpan);
        /// <summary>
        /// 注销服务
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        bool UnRegister(Guid key);
    }
}
